﻿// 功能：多行文本框
// 描述：
// 作者：温伟鹏
// 日期：2010/5/18 10:24:57

using System;
using System.Runtime.InteropServices;
using MeizuSDK.Core;
using System.Drawing;
using MeizuSDK.Drawing;

namespace MeizuSDK.Presentation
{
    /// <summary>
    /// 多行文本框
    /// </summary>
    public class MultilineTextBox : TextBoxBase
    {
        #region DllImport

        [DllImport("MZFCWrapper.dll")]
        private static extern IntPtr UiEditWrapperCtor(OnFocusedFunc focused,OnLostFocusFunc lostFocus);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperDispose(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern string UiEditWrapperGetText(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperSetText(IntPtr pObj, [MarshalAs(UnmanagedType.LPWStr)] string text);

        [DllImport("MZFCWrapper.dll")]
        private static extern int UiEditWrapperGetColorBg(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperSetColorBg(IntPtr pObj, int clr);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperSetTextColor(IntPtr pObj, int clr);

        [DllImport("MZFCWrapper.dll")]
        private static extern int UiEditWrapperGetEditBgType(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperSetEditBgType(IntPtr pObj, int nEditBgType);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperSetLeftInvalid(IntPtr pObj, int offset);

        [DllImport("MZFCWrapper.dll")]
        private static extern int UiEditWrapperGetLeftInvalid(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperSetRightInvalid(IntPtr pObj, int offset);

        [DllImport("MZFCWrapper.dll")]
        private static extern int UiEditWrapperGetRightInvalid(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperSetTopInvalid(IntPtr pObj, int offset);

        [DllImport("MZFCWrapper.dll")]
        private static extern int UiEditWrapperGetTopInvalid(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperSetBottomInvalid(IntPtr pObj, int offset);

        [DllImport("MZFCWrapper.dll")]
        private static extern int UiEditWrapperGetBottomInvalid(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperSetLineSpace(IntPtr pObj, int nLineSpace);

        [DllImport("MZFCWrapper.dll")]
        private static extern int UiEditWrapperGetLineSpace(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperEnableGridLines(IntPtr pObj, bool bEnable);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperEnableRichTextFormat(IntPtr pObj, bool bEnable);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool UiEditWrapperIsRichTextFormat(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperSetReadOnly(IntPtr pObj, bool status);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool UiEditWrapperIsReadOnly(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperEnableInsideScroll(IntPtr pObj, bool bEnable);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool UiEditWrapperIsInsideScroll(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperEnableUndo(IntPtr pObj, bool bEnable);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool UiEditWrapperIsUndoEnabled(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperSetLinkMode(IntPtr pObj, uint linkMode);

        [DllImport("MZFCWrapper.dll")]
        private static extern uint UiEditWrapperGetLinkMode(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperEnableCopy(IntPtr pObj, bool bEnable);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool UiEditWrapperIsEnableCopy(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperEnableAutoOpenSip(IntPtr pObj, bool bEnable);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperEnableZoomIn(IntPtr pObj, bool bEnable);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool UiEditWrapperIsEnableAutoOpenSip(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperUndo(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperRedo(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperClear(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool UiEditWrapperIsEmpty(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperSetCaretPos(IntPtr pObj, uint nRow, uint nCol);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperGetCaretPos(IntPtr pObj, ref uint nRow, ref uint nCol);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperShowCaret(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperSetTip(IntPtr pObj, [MarshalAs(UnmanagedType.LPWStr)]string text);

        // 输入法
        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperSetSipMode(IntPtr pObj, uint dwMode, uint dwSipOffset);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperSetSipModeEx(IntPtr pObj, uint dwMode, uint dwSipOffset, [MarshalAs(UnmanagedType.LPTStr)]string strSip);

        [DllImport("MZFCWrapper.dll")]
        private static extern void UiEditWrapperSwitchSipMode(IntPtr pObj, uint dwMode, uint dwSipOffset);
        #endregion

        #region 私有变量

        OnFocusedFunc pFocused;
        OnLostFocusFunc pLostFocus;

        private string strTip;
        private bool enableGridLines;
        private bool enableMagnifier;
        /// <summary>
        /// 编辑框字体颜色
        /// </summary>
        private Color foreColor;
        #endregion

        #region 公共属性
        /// <summary>
        /// 获取或设置多行文本框的提示文本。该文本在有输入后自动消失
        /// </summary>
        public override string Tip
        {
            get
            {
                return strTip;
            }
            set
            {
                if (value != strTip)
                {
                    strTip = value;
                    UiEditWrapperSetTip(Handle, value);
                }
            }
        }
        /// <summary>
        /// 获取或设置多行文本框中显示的文本
        /// </summary>
        public override string Text
        {
            get
            {
                return base.Text;
            }
            set
            {
                //base.Text = value;
                UiEditWrapperSetText(Handle, value);
                Invalidate();
                Update();
            }
        }
        /// <summary>
        /// 获取或设置多行文本框背景样式
        /// </summary>
        public MultilineTextBoxBgType BackgroundType
        {
            get
            {
                return (MultilineTextBoxBgType)UiEditWrapperGetEditBgType(Handle);
            }
            set
            {
                UiEditWrapperSetEditBgType(Handle, (int)value);
            }
        }
        /// <summary>
        /// 获取或设置编辑控件的背景色
        /// </summary>
        public Color BackColor
        {
            get
            {
                int clr = UiEditWrapperGetColorBg(Handle);

                return MzDrawHelper.ConvertRgbToColor(clr);
            }
            set
            {
                int clr = value.ToArgb();

                UiEditWrapperSetColorBg(Handle, clr);
            }
        }
        /// <summary>
        /// 获取或设置编辑控件的前景色
        /// </summary>
        public override Color ForeColor
        {
            get
            {
                if (foreColor == Color.Empty)
                    foreColor = base.ForeColor;
                return foreColor;
            }
            set
            {
                this.foreColor = value;
                UiEditWrapperSetTextColor(Handle, value.ToArgb());
            }
        }
        /// <summary>
        /// 获取或设置编辑框左侧无效区域宽度
        /// </summary>
        public override int LeftInvalidOffset
        {
            get
            {
                return UiEditWrapperGetLeftInvalid(Handle);
            }
            set
            {
                UiEditWrapperSetLeftInvalid(Handle, value);
            }
        }
        /// <summary>
        /// 获取或设置编辑框右侧无效区域宽度
        /// </summary>
        public override int RightInvalidOffset
        {
            get
            {
                return UiEditWrapperGetRightInvalid(Handle);
            }
            set
            {
                UiEditWrapperSetRightInvalid(Handle, value);
            }
        }
        /// <summary>
        /// 获取或设置编辑框顶部无效区域宽度
        /// </summary>
        public int TopInvalidOffset
        {
            get
            {
                return UiEditWrapperGetTopInvalid(Handle);
            }
            set
            {
                UiEditWrapperSetTopInvalid(Handle, value);
            }
        }
        /// <summary>
        /// 获取或设置编辑框底部无效区域宽度
        /// </summary>
        public int BottomInvalidOffset
        {
            get
            {
                return UiEditWrapperGetBottomInvalid(Handle);
            }
            set
            {
                UiEditWrapperSetBottomInvalid(Handle, value);
            }
        }
        /// <summary>
        /// 获取或设置行距
        /// </summary>
        public int LineSpace
        {
            get
            {
                return UiEditWrapperGetLineSpace(Handle);
            }
            set
            {
                UiEditWrapperSetLineSpace(Handle, value);
            }
        }
        /// <summary>
        /// 获取或设置一个标志，指示是否启用表格线
        /// </summary>
        public bool GridLines
        {
            get
            {
                return enableGridLines;
            }
            set
            {
                if (value != enableGridLines)
                {
                    enableGridLines = value;
                    UiEditWrapperEnableGridLines(Handle, value);
                }
            }
        }
        /// <summary>
        /// 获取或设置一个值，指示编辑框是否支持丰富的文字排版,表情识别,图片功能
        /// </summary>
        public bool RichTextFormat
        {
            get
            {
                return UiEditWrapperIsRichTextFormat(Handle);
            }
            set
            {
                UiEditWrapperEnableRichTextFormat(Handle, value);
            }
        }
        /// <summary>
        /// 获取或设置一个值，指示编辑框是否只读
        /// </summary>
        public bool ReadOnly
        {
            get
            {
                return UiEditWrapperIsReadOnly(Handle);
            }
            set
            {
                UiEditWrapperSetReadOnly(Handle, value);
                UiEditWrapperEnableZoomIn(Handle, this.enableMagnifier);// 启用/禁用放大镜
            }
        }
        /// <summary>
        /// 获取或设置一个值，指示编辑框是否启用放大镜
        /// （注意：启用放大镜会使应用程序内存占用大于10MB，而且无法释放，因此建议不启用放大镜）
        /// </summary>
        public bool EnableMagnifier
        {
            get
            {
                return this.enableMagnifier;
            }
            set
            {
                this.enableMagnifier = value;
                UiEditWrapperSetReadOnly(Handle, ReadOnly);// 重设一次编辑框的只读属性
                UiEditWrapperEnableZoomIn(Handle, value);
            }
        }
        /// <summary>
        /// 获取或设置一个值，指示编辑框是否支持内部滚动
        /// </summary>
        public bool InsideScroll
        {
            get
            {
                return UiEditWrapperIsInsideScroll(Handle);
            }
            set
            {
                UiEditWrapperEnableInsideScroll(Handle, value);
            }
        }
        /// <summary>
        /// 获取或设置一个值，指示编辑框是否支持撤销
        /// </summary>
        public bool CanUndo
        {
            get
            {
                return UiEditWrapperIsUndoEnabled(Handle);
            }
            set
            {
                UiEditWrapperEnableUndo(Handle, value);
            }
        }
        /// <summary>
        /// 获取或设置一个值，指示编辑框是否支持复制
        /// </summary>
        public bool CanCopy
        {
            get
            {
                return UiEditWrapperIsEnableCopy(Handle);
            }
            set
            {
                UiEditWrapperEnableCopy(Handle, value);
            }
        }
        /// <summary>
        /// 获取或设置一个值，指示编辑框是否自动打开输入法
        /// </summary>
        public bool AutoOpenSip
        {
            get
            {
                return UiEditWrapperIsEnableAutoOpenSip(Handle);
            }
            set
            {
                UiEditWrapperEnableAutoOpenSip(Handle, value);
            }
        }
        /// <summary>
        /// 获取或设置一个值，指示文本框是否为空
        /// </summary>
        public bool IsEmpty
        {
            get
            {
                return UiEditWrapperIsEmpty(Handle);
            }
        }
        /// <summary>
        /// 获取或设置编辑框的光标位置
        /// </summary>
        public CaretPosition CaretPosition
        {
            get
            {
                uint nRow = 0;
                uint nCol = 0;

                UiEditWrapperGetCaretPos(Handle, ref nRow, ref nCol);

                return new CaretPosition(nRow, nCol);
            }
            set
            {
                UiEditWrapperSetCaretPos(Handle, value.Row, value.Column);
                ShowCaret();
            }
        }
        #endregion

        #region 构造函数
        /// <summary>
        /// 构造多行文本框实例
        /// </summary>
        public MultilineTextBox()
            : base()
        {
            pFocused = new OnFocusedFunc(InternalOnFocused);
            pLostFocus = new OnLostFocusFunc(InternalOnLostFocus);

            Handle = UiEditWrapperCtor(pFocused, pLostFocus);
            SetID();
            BackgroundType = MultilineTextBoxBgType.RoundTopShadow;
        }
        #endregion

        #region 函数
        /// <summary>
        /// 撤销编辑框的上一次操作
        /// </summary>
        public void Undo()
        {
            UiEditWrapperUndo(Handle);
        }
        /// <summary>
        /// 重复编辑框的上一次操作
        /// </summary>
        public void Redo()
        {
            UiEditWrapperRedo(Handle);
        }
        /// <summary>
        /// 清空文本框内容
        /// </summary>
        public void Clear()
        {
            UiEditWrapperClear(Handle);
        }
        /// <summary>
        /// 根据当前光标的行列位置,重画光标
        /// </summary>
        public void ShowCaret()
        {
            UiEditWrapperShowCaret(Handle);
        }
        /// <summary>
        /// 设置文本框输入法模式
        /// </summary>
        /// <param name="sipMode">输入法模式</param>
        public void SetSipMode(SipMode sipMode)
        {
            SetSipMode(sipMode, SipHelper.DefaultSipOffset);
        }
        /// <summary>
        /// 设置文本框输入法模式
        /// </summary>
        /// <param name="sipMode">输入法模式</param>
        /// <param name="offset">输入法离屏幕底部的偏移高度,如果值为0xffffffff，采用系统默认值</param>
        public void SetSipMode(SipMode sipMode, uint offset)
        {
            if (!IsHandleCreated)
                return;

            uint mode = (uint)sipMode;
            try
            {
                UiEditWrapperSetSipMode(Handle, mode, offset);
            }
            catch (Exception) { }
        }
        /// <summary>
        /// 设置文本框输入法模式
        /// </summary>
        /// <param name="sipMode">输入法模式</param>
        /// <param name="offset">输入法离屏幕底部的偏移高度,如果值为0xffffffff，采用系统默认值</param>
        /// <param name="sipText"></param>
        public void SetSipMode(SipMode sipMode, uint offset, string sipText)
        {
            if (!IsHandleCreated)
                return;

            uint mode = (uint)sipMode;
            try
            {
                UiEditWrapperSetSipModeEx(Handle, mode, offset, sipText);
            }
            catch (Exception) { }
        }
        /// <summary>
        /// 切换编辑器输入法模式 
        /// </summary>
        /// <param name="sipMode">输入法模式</param>
        public void SwitchSipMode(SipMode sipMode)
        {
            SwitchSipMode(sipMode, SipHelper.DefaultSipOffset);
        }
        /// <summary>
        /// 切换编辑器输入法模式
        /// </summary>
        /// <param name="sipMode">输入法模式</param>
        /// <param name="offset">输入法离屏幕底部的偏移高度,如果值为0xffffffff，采用系统默认值</param>
        public void SwitchSipMode(SipMode sipMode, uint offset)
        {
            if (!IsHandleCreated)
                return;

            uint mode = (uint)sipMode;
            try
            {
                UiEditWrapperSwitchSipMode(Handle, mode, offset);
            }
            catch (Exception) { }
        }
        /// <summary>
        /// 引发 SizeChanged 事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnSizeChanged(EventArgs e)
        {
            // 防止文本框大小改变后，文本内容无法自适应文本框
            if (!IsEmpty)
            {
                string oldText = Text;

                Clear();

                Text = oldText;
            }

            base.OnSizeChanged(e);
        }
        #endregion
    }
}
